# This is the profiler for table/s and database/s.
# This can be used to gather statistics such as number of columns, number of records, primary key.
# This can be used before ETL operations so that user can get the structural overview of the table.

class Profile

      class Rule

          def self.method_missing(method_name)
              puts method_name  
              method_name_array = method_name.to_s.split("_")
              $column_number = method_name_array[2..3].join("_")
              $table_name = method_name_array[6..(method_name_array.length-1)].join("_")
              return Profile::Rule.new
          end

            
          def self.profile_single_column(column_name,table_name,connection)    
              col_struc = connection.execute("desc #{table_name}")
              col_struc.each do |col|
                    column_one = first_letter_capital(col[0])
                    column_two = first_letter_capital(column_name)
                    if col[0] == column_name || col[0].upcase == column_name || col[0].downcase == column_name || column_one == column_two
                        generate_column_profile(col,table_name,connection)
                    end	
              end          
          end



          def under connection
              all_columns = connection.execute("desc #{$table_name}")
              req_columns = get_columns_from_positions($column_number,all_columns)
              for column in req_columns
                  generate_column_profile(column,$table_name,connection)
              end
          end             
    
      end  
      
      
      # This is the method missing for dynamic profiling of the tables 
      def self.method_missing(method_name)
            method_array = method_name.to_s.split("_")
            $table_name = method_array[(method_array.index("is")+1)..(method_array.length-1)].join("_")  
            return Profile.new
      end  


      # This is when you want to profile entire database to which connection has been made.
      def self.connection_is(connection)
          all_tables = connection.tables
          for table in all_tables
              Profile.generate_profile(table,connection)
          end
      end  


      # This is the method for passing connection argument for the table profiling.
      # This works in collaboration with other methods.
      def under(connection)
          Profile.generate_profile($table_name,connection) 
      end
   
   
      # This is for generating profiles of tables under different databases.
      def self.generate_profile_for_tables(options={})
          options.each{|key,value|
                for table in key
                    Profile.generate_profile(table,value)
                end
          }    
      end
   
   
      # This is for profiling multiple databases.
      def Profile.generate_profile_for_databases(conn_array)
          for conn in conn_array
              Profile.connection_is(conn)
          end  
      end


      # This is the actual method for generating profiles.
      # Here more features can be added.
      # Up on agenda are:
            #   Constraint wise column distribution
            #   Datatype wise column distribution
      def self.generate_profile(table_name,connection)
            column_counter = 0
            record_counter = 0
            all_columns = connection.execute("desc #{table_name}")
            for field in all_columns
                  if field.include?"PRIMARY KEY" or field.include?"primary key" or field.include?"PRI"
                      puts "Primary key for the table is:#{field.to_a[0]}"
                  end  
                  column_counter = column_counter + 1
            end
            all_records = connection.execute("select * from #{table_name}")
            for counter in all_records
                  record_counter = record_counter + 1
            end
            puts "Total number of columns in the table are:#{column_counter}"  
            puts "Total number of records in the table are:#{record_counter}"   
            puts
      end

end  